var Aspect;
(function (Aspect) {
    var WeaveEvent = (function () {
        function WeaveEvent(name, method, error) {
            if (typeof error === "undefined") { error = null; }
            this.name = name;
            this.method = method;
            this.error = error;
        }
        WeaveEvent.prototype.toString = function () {
            var eventString = 'Event: ' + this.name + '. Method: ' + this.method + '.';
            if(this.error) {
                eventString += ' Error: ' + this.error.name + ' ' + this.error.message + '.';
            }
            return eventString;
        };
        return WeaveEvent;
    })();
    Aspect.WeaveEvent = WeaveEvent;    
    var Weaver = (function () {
        function Weaver() { }
        Weaver.before = function before(target, method, action) {
            var old = target.prototype[method];
            var event = new WeaveEvent('before', method);
            target.prototype[method] = function () {
                var args = Array.prototype.slice.call(arguments);
                action.apply(this, [
                    event, 
                    args
                ]);
                var result = old.apply(this, args);
                return result;
            };
        }
        Weaver.after = function after(target, method, action) {
            var old = target.prototype[method];
            var event = new WeaveEvent('after', method);
            target.prototype[method] = function () {
                var args = Array.prototype.slice.call(arguments);
                var result = old.apply(this, args);
                action.apply(this, [
                    event, 
                    args
                ]);
                return result;
            };
        }
        Weaver.afterAll = function afterAll(target, method, action) {
            var old = target.prototype[method];
            var event = new WeaveEvent('afterAll', method);
            target.prototype[method] = function () {
                var args = Array.prototype.slice.call(arguments);
                try  {
                    var result = old.apply(this, args);
                    return result;
                }finally {
                    action.apply(this, [
                        event, 
                        args
                    ]);
                }
            };
        }
        Weaver.error = function error(target, method, action) {
            var old = target.prototype[method];
            target.prototype[method] = function () {
                var args = Array.prototype.slice.call(arguments);
                try  {
                    var result = old.apply(this, args);
                    return result;
                } catch (ex) {
                    var event = new WeaveEvent('error', method, ex);
                    action.apply(this, [
                        event, 
                        args
                    ]);
                    throw ex;
                }
            };
        }
        return Weaver;
    })();
    Aspect.Weaver = Weaver;    
})(Aspect || (Aspect = {}));

